package cz.cuni.mff.ufal.volk;

import java.util.Collection;

import cz.cuni.mff.ufal.volk.events.NabaztagEventListener;

/**
 * The enumeration representing actions made by user to the Nabaztag.
 *
 * @author Bartłomiej Etenkowski
 */
public enum UserAction {
  /** The Nabaztag has received time-out from the server. */
  TIME_OUT(0) {
    @Override
    public void process(Collection<NabaztagEventListener> listeners, NabaztagProxy nab, String argumentString) {
    	synchronized (listeners) {
    		for (NabaztagEventListener listener : listeners) {
    			listener.onTimeout(nab);
    		}
    	}
    }
  },

  /** The User has pressed the button twice. */
  DOUBLE_CLICK(1) {
    @Override
    public void process(Collection<NabaztagEventListener> listeners, NabaztagProxy nab, String argumentString) {
      synchronized (listeners) {
        for (NabaztagEventListener listener : listeners)
          listener.onDoubleClick(nab);
      }
    }
  },

  /** The Nabaztag has completed the execution of a command received from the server. */
  COMPLETED(2) {
    @Override
    public void process(Collection<NabaztagEventListener> listeners, NabaztagProxy nab, String argumentString) {
    	synchronized(listeners) {
    		for (NabaztagEventListener listener: listeners) {
    			listener.onCompleted(nab);
    		}
    	}
    }
  },

  /** The User has pressed the button once. */
  SINGLE_CLICK(3) {
    @Override
    public void process(Collection<NabaztagEventListener> listeners, NabaztagProxy nab, String argumentString) {
      synchronized (listeners) {
        for (NabaztagEventListener listener : listeners)
          listener.onClick(nab);
      }
    }
  },

  UNK_4(4) {
    @Override
    public void process(Collection<NabaztagEventListener> listeners, NabaztagProxy nab, String argumentString) {
      throw new UnsupportedOperationException();
    }
  },

  /** The User has pressed the button on the Nabaztag's head and interrupted voice output.s */
  VOICE_INTERRUPTED(5) {
    @Override
    public void process(Collection<NabaztagEventListener> listeners, NabaztagProxy nab, String argumentString) {
      synchronized (listeners) {
      	for (NabaztagEventListener listener : listeners)
      		listener.onVoiceInterrupted(nab);
      }
    }
  },

  UNK_6(6) {
    @Override
    public void process(Collection<NabaztagEventListener> listeners, NabaztagProxy nab, String argumentString) {
      throw new UnsupportedOperationException();
    }
  },

  UNK_7(7) {
    @Override
    public void process(Collection<NabaztagEventListener> listeners, NabaztagProxy nab, String argumentString) {
      throw new UnsupportedOperationException();
    }
  },

  /** The ear positions were changed by the user. */
  EAR_POSITIONS(8) {
    @Override
    public void process(Collection<NabaztagEventListener> listeners, NabaztagProxy nab, String argumentString) {
      if (argumentString.length() != 3)
        throw new IllegalArgumentException("The argumentString argument is incorrect");
      int left = Integer.parseInt(argumentString.substring(0, 1), 16);
      int right = Integer.parseInt(argumentString.substring(2, 3), 16);
      synchronized (listeners) {
        for (NabaztagEventListener listener : listeners)
          listener.onEarsMoved(nab, left, right);
      }
    }
  };

  public abstract void process(Collection<NabaztagEventListener> listeners, NabaztagProxy nab, String argumentString);

  private final int id;

  public int getId() {
    return id;
  }

  private UserAction(int id) {
    this.id = id;
  }

  public static UserAction byId(int id) {
    UserAction[] actions = values();
    if (id < 0 || id >= actions.length)
      return null;
    else
      return actions[id];
  }

  public static UserAction byCharacterId(char id) {
    return byId(id - '0');
  }
}
